﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Windows.Forms;


namespace Marmat.Forms
{
    [ToolboxItem(true)]
    public partial class TabFormPanel : System.Windows.Forms.UserControl, IControl
    {

        /* TODO ERROR: Skipped RegionDirectiveTrivia */
        public TabFormPanel()
        {
            // 组件设计器需要此调用。
            this.InitializeComponent();
            this.SetStyle(ControlStyles.ResizeRedraw, true); // 尺寸变化后绘制
            this.SetStyle(ControlStyles.Opaque, false); // 改善绘图质量
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); // 使控件支持透明色
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            _BackColor = base.BackColor;
            base.BackColor = Color.Transparent;
            this.ContextMenuStrip1.Renderer = new TabFormPanelMenuStripRenderer();
            this.FormsContextMenuStrip.Renderer = new TabFormPanelMenuStripRenderer();
        }
        /* TODO ERROR: Skipped EndRegionDirectiveTrivia *//* TODO ERROR: Skipped RegionDirectiveTrivia */
        /// <summary>
        /// 鼠标移动时促发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks></remarks>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            foreach (System.Windows.Forms.Form frm in this.Forms)
            {
                if (this.Rectangles[frm].Contains(e.Location))
                {
                    this.MouseMoveFrom = frm;
                    Image Image = Properties.Resources.TabFormPanel_arrow0;
                    int Image_x = this.Rectangles[frm].Right - Image.Width - 5;
                    int Image_y = (int)Math.Round((this.Rectangles[frm].Bottom - Image.Height) / 2d);
                    this.CloseRect = new Rectangle(Image_x, Image_y, Image.Width, Image.Height).Contains(e.Location);
                    this.Invalidate(this.Rectangle);
                    return;
                }
            }

            this.MouseMoveFrom = null;
            this.Invalidate(this.Rectangle);
        }

        private Rectangle CloseRectangle;
        /// <summary>
        /// 按下鼠标后促发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks></remarks>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)
            {
                foreach (System.Windows.Forms.Form frm in this.Forms)
                {
                    if (this.Rectangles[frm].Contains(e.Location))
                    {
                        this.SelectedForm = frm;
                        if (this.ShowClose == true)
                        {
                            Image Image = Properties.Resources.TabFormPanel_arrow0;
                            int Image_x = this.Rectangles[frm].Right - Image.Width - 5;
                            int Image_y = (int)Math.Round((this.Rectangles[frm].Bottom - Image.Height) / 2d);
                            this.CloseRectangle = new Rectangle(Image_x, Image_y, Image.Width, Image.Height);
                            if (this.CloseRectangle.Contains(e.Location) == false)
                            {
                                this.CloseRectangle = default;
                            }
                        }

                        this.Invalidate(this.Rectangle);
                        break;
                    }
                }
            }
            else
            {
                foreach (System.Windows.Forms.Form frm in this.Forms)
                {
                    if (this.Rectangles[frm].Contains(e.Location))
                    {
                        if (frm is object)
                        {
                            this.ContextMenuStrip1.Tag = frm;
                            var p = this.PointToScreen(new Point(0, 0));
                            this.ToolStripMenuItem1.Enabled = frm is not null;
                            this.ToolStripMenuItem3.Enabled = !ReferenceEquals(this.Forms[0], frm);
                            this.ToolStripMenuItem4.Enabled = !ReferenceEquals(this.Forms[this.Forms.Count - 1], frm);
                            this.ToolStripMenuItem2.Enabled = !(this.Forms.Count == 1 && ReferenceEquals(this.Forms[0], frm));
                            this.关闭所有ToolStripMenuItem.Enabled = this.Forms.Count > 1;
                            this.ContextMenuStrip1.Show(p.X + e.X, p.Y + this.Padding.Top + 1);
                        }

                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 松开鼠标后促发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks></remarks>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                for (int i = 0, loopTo = this.Forms.Count - 1; i <= loopTo; i++)
                {
                    if (this.ShowClose == false)
                        return;
                    var frm = this.Forms[i];
                    if (this.Rectangles[frm].Contains(e.Location))
                    {
                        Image Image = Properties.Resources.TabFormPanel_arrow0;
                        int Image_x = this.Rectangles[frm].Right - Image.Width - 5;
                        int Image_y = (int)Math.Round((this.Rectangles[frm].Bottom - Image.Height) / 2d);
                        var Rect = new Rectangle(Image_x, Image_y, Image.Width, Image.Height);
                        if (Rect.Contains(e.Location) && this.CloseRectangle.Contains(e.Location))
                        {
                            var EventArgs = new FormClosingEventArgs();
                            EventArgs.m_Form = frm;
                            FormClosing?.Invoke(this, EventArgs);
                            if (EventArgs.Cancel == false)
                            {
                                frm.Close();
                            }
                        }

                        this.Invalidate(this.Rectangle);
                        break;
                    }
                }
            }

            base.OnMouseUp(e);
        }

        public event FormClosingEventHandler FormClosing;

        public delegate void FormClosingEventHandler(object Sender, FormClosingEventArgs e);
        /// <summary>
        /// 鼠标离开后促发
        /// </summary>
        /// <param name="e"></param>
        /// <remarks></remarks>
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this.MouseMoveFrom = null;
            this.Invalidate(this.Rectangle);
        }
        /* TODO ERROR: Skipped EndRegionDirectiveTrivia */
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public TabFormPanelRenderer Renderer { get; set; }

        internal System.Windows.Forms.Form MouseMoveFrom;
        private readonly TextFormatFlags _flags = TextFormatFlags.VerticalCenter | TextFormatFlags.PreserveGraphicsClipping;
        /// <summary>
        /// 绘制事件
        /// </summary>
        /// <param name="e"></param>
        /// <remarks></remarks>
        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.ShowTabs == false)
                return;
            int Left = default, Width, TextLeft = default, @int = default;
            var Renderer = this.Renderer;
            if (Renderer is null)
            {
                Renderer = new TabFormPanelRenderer(this);
            }
            // 绘制背景===================================================
            Renderer.RaiseOnPaint(e);

            // 外观优化参数=================================================
            e.Graphics.SetClip(new Rectangle(0, 0, this.Width - 15, this.Padding.Top));
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            // 开始绘制选项卡集合===========================================
            for (int i = 0, loopTo = this.Forms.Count - 1; i <= loopTo; i++)
            {
                var Frm = this.Forms[i];
                Width = this.GetRectangleWidth(Frm);
                if (i >= this.FirstIndex && Left + Width < this.Width - 15 || i >= this.FirstIndex && @int == 0)
                {
                    var TabRectangle = new Rectangle(Left, 4, Width, this.Padding.Top);
                    Rectangle IconRectangle = default;
                    Rectangle TextRectangle = default;
                    Rectangle CloseRectangle = default;
                    this.Rectangles[Frm] = TabRectangle;
                    // 绘制选项卡矩形===========================================
                    var TabFormPaint = new TabFormPaintEventArgs();
                    TabFormPaint.Form = Frm;
                    TabFormPaint.Graphics = e.Graphics;
                    TabFormPaint.Rectangle = TabRectangle;
                    Renderer.RaiseOnTabPaint(TabFormPaint);
                    // Using Brushes As New LinearGradientBrush(TabRectangle, Me.TopColor, Me.BottomColor, 90)
                    // If Frm Is Me.SelectedForm Then
                    // Brushes.LinearColors = {Me.SelectedTopColor, Me.SelectedBottomColor}
                    // ElseIf Frm Is Me.MouseMoveFrom Then
                    // Brushes.LinearColors = {Me.MouseEnterTopColor, Me.MouseEnterBottomColor}
                    // End If
                    // Dim Path As System.Drawing.Drawing2D.GraphicsPath = GDI.GetRoundRectangle(TabRectangle, Me.ArcRadius)
                    // e.Graphics.FillPath(Brushes, Path)
                    // End Using

                    // 绘制图标==================================================
                    if (this.ShowIcon == true && Frm.Icon is object)
                    {
                        Image icon = null;
                        if (Frm.Icon is object)
                        {
                            icon = Frm.Icon.ToBitmap().GetThumbnailImage(16, 16, () => false, IntPtr.Zero);
                        }

                        int Icon_x = TabRectangle.Left + 5;
                        int Icon_y = (int)Math.Round((TabRectangle.Bottom - icon.Height) / 2d);
                        IconRectangle = new Rectangle(Icon_x, Icon_y, icon.Width, icon.Height);
                        e.Graphics.DrawImage(icon, IconRectangle);
                    }

                    // 绘制文字===================================================
                    if (this.ShowIcon == true && Frm.Icon is object)
                    {
                        TextLeft = 26;
                    }

                    var TextRect = new Rectangle(TabRectangle.X + TextLeft, TabRectangle.Y, TabRectangle.Width - TextLeft, TabRectangle.Height);
                    if (ReferenceEquals(Frm, this.SelectedForm))
                    {
                        TextRenderer.DrawText(e.Graphics, Frm.Text, this.SelectedFont, TextRect, this.SelectedForeColor, this._flags);
                    }
                    else if (ReferenceEquals(Frm, this.MouseMoveFrom))
                    {
                        TextRenderer.DrawText(e.Graphics, Frm.Text, this.MouseEnterFont, TextRect, this.MouseEnterForeColor, this._flags);
                    }
                    else
                    {
                        TextRenderer.DrawText(e.Graphics, Frm.Text, this.Font, TextRect, this.NormalForeColor, this._flags);
                    }

                    // 绘制关闭按钮===============================================
                    if (this.ShowClose == true && this.GetClose(Frm))
                    {
                        Image Image = Properties.Resources.TabFormPanel_arrow0;
                        if (ReferenceEquals(this.MouseMoveFrom, Frm))
                        {
                            if (this.CloseRect == true)
                            {
                                Image = Properties.Resources.TabFormPanel_arrow1;
                            }

                            int Image_x = TabRectangle.Right - Image.Width - 5;
                            int Image_y = (int)Math.Round((TabRectangle.Bottom - Image.Height) / 2d);
                            e.Graphics.DrawImage(Image, Image_x, Image_y);
                        }
                    }

                    Left += TabRectangle.Width;
                    @int = 1;
                }
                else
                {
                    this.Rectangles[Frm] = default;
                }
            }
        }

        private void ContextMenuStrip_Opening(object sender, CancelEventArgs e)
        {
            this.FormsContextMenuStrip.Items.Clear();
            foreach (System.Windows.Forms.Form frm in this.Forms)
            {
                Image icon = null;
                if (frm.Icon is object)
                {
                    icon = frm.Icon.ToBitmap().GetThumbnailImage(16, 16, () => false, IntPtr.Zero);
                }

                var Too = new ToolStripMenuItem(frm.Text, icon);
                Too.Tag = frm;
                if (ReferenceEquals(frm, this.SelectedForm))
                {
                    Too.Checked = true;
                    Too.BackColor = Color.FromArgb(196, 225, 255);
                }

                this.FormsContextMenuStrip.Items.Add(Too);
            }
        }

        /// <summary>
        /// 展开窗口列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks></remarks>
        private void PictureBox1_Click(object sender, EventArgs e)
        {
            if (this.Forms.Count > 0 && sender is Control control)
            {
                Point p = control.PointToScreen(new Point(0, 0));
                this.FormsContextMenuStrip.Show(p.X, p.Y + control.Height);
            }
        }

        private void ContextMenuStrip_ItemClicked(object sender, System.Windows.Forms.ToolStripItemClickedEventArgs e)
        {
            this.SelectedForm = (System.Windows.Forms.Form)e.ClickedItem.Tag;
            this.Method_layout();
            this.Invalidate(this.Rectangle);
        }

        /// <summary>
        /// 返回选项卡矩形的宽度
        /// </summary>
        /// <param name="frm"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public int GetRectangleWidth(System.Windows.Forms.Form frm)
        {
            int MinWidth = 80; // 最小矩形宽度
            int MaxWidth = 200; // 最大矩形宽度
            int Spacing = 5; // 项目的间距
            int Result = Spacing; // 矩形的宽度

            // 如果显示Icon并且窗体Icon不为空的话
            if (this.ShowIcon == true && frm.Icon is object)
            {
                Result += 16 + Spacing;
            }

            // 如果窗体标题不为空的话
            if (!string.IsNullOrEmpty(frm.Text))
            {
                int TextWidth = TextRenderer.MeasureText(frm.Text, this.Font, new Size(this.Width, this.Padding.Top), this._flags).Width;
                Result += TextWidth + Spacing;
            }

            // 是否显示关闭按钮
            if (this.ShowClose && this.GetClose(frm))
            {
                Result += 16 + Spacing;
            }

            Result = Math.Max(MinWidth, Result);
            Result = Math.Min(MaxWidth, Result);
            return Result;
        }

        /// <summary>
        /// 选项卡布局
        /// </summary>
        /// <remarks></remarks>
        internal void Method_layout()
        {
            int Width = default, Page = default;
            // 获取当前选定的选项卡序号===============================
            for (int i = 0, loopTo = this.Forms.Count - 1; i <= loopTo; i++)
            {
                if (ReferenceEquals(this.Forms[i], this.SelectedForm))
                {
                    Page = i;
                    break;
                }
            }
            // 计算当前序号为首个页签时页签集合的宽度=================
            for (int i = Page, loopTo1 = this.Forms.Count - 1; i <= loopTo1; i++)
                Width += this.GetRectangleWidth(this.Forms[i]);
            // 如果默认整个页签的宽度没有空间的宽度宽时，适当调整首个页签序号
            if (Width < this.Width - 15)
            {
                for (int i = Page - 1; i >= 0; i -= 1)
                {
                    int w = this.GetRectangleWidth(this.Forms[i]);
                    if (Width + w < this.Width - 15)
                    {
                        Page -= 1;
                        Width += w;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            this.FirstIndex = Page;
        }

        /// <summary>
        /// 调整大小时促发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks></remarks>
        private void Panel1_Resize(object sender, EventArgs e)
        {
            this.Method_layout();
        }

        private void ContextMenuStrip1_ItemClicked(object sender, System.Windows.Forms.ToolStripItemClickedEventArgs e)
        {
            System.Windows.Forms.Form form = (System.Windows.Forms.Form)this.ContextMenuStrip1.Tag;
            switch (e.ClickedItem.Name ?? "")
            {
                case var @case when @case == (this.ToolStripMenuItem1.Name ?? ""):
                    {
                        if (form is object)
                        {
                            var EventArgs = new FormClosingEventArgs();
                            EventArgs.m_Form = form;
                            FormClosing?.Invoke(this, EventArgs);
                            if (EventArgs.Cancel == false)
                            {
                                form.Close();
                            }
                        }

                        break;
                    }

                case var case1 when case1 == (this.ToolStripMenuItem2.Name ?? ""):
                    {
                        var list = new List<System.Windows.Forms.Form>();
                        foreach (System.Windows.Forms.Form frm in this.Forms)
                        {
                            if (!ReferenceEquals(frm, form))
                            {
                                list.Add(frm);
                            }
                        }

                        foreach (System.Windows.Forms.Form f in list)
                        {
                            var EventArgs = new FormClosingEventArgs();
                            EventArgs.m_Form = f;
                            FormClosing?.Invoke(this, EventArgs);
                            if (EventArgs.Cancel == false)
                            {
                                f.Close();
                            }
                        }

                        break;
                    }

                case var case2 when case2 == (this.ToolStripMenuItem3.Name ?? ""):
                    {
                        var list = new List<System.Windows.Forms.Form>();
                        for (int i = 0, loopTo = this.Forms.Count - 1; i <= loopTo; i++)
                        {
                            if (ReferenceEquals(this.Forms[i], form))
                            {
                                break;
                            }

                            list.Add(this.Forms[i]);
                        }

                        foreach (System.Windows.Forms.Form f in list)
                        {
                            var EventArgs = new FormClosingEventArgs();
                            EventArgs.m_Form = f;
                            FormClosing?.Invoke(this, EventArgs);
                            if (EventArgs.Cancel == false)
                            {
                                f.Close();
                            }
                        }

                        break;
                    }

                case var case3 when case3 == (this.ToolStripMenuItem4.Name ?? ""):
                    {
                        var list = new List<System.Windows.Forms.Form>();
                        for (int i = this.Forms.Count - 1; i >= 0; i -= 1)
                        {
                            if (ReferenceEquals(this.Forms[i], form))
                            {
                                break;
                            }

                            list.Add(this.Forms[i]);
                        }

                        foreach (System.Windows.Forms.Form f in list)
                        {
                            var EventArgs = new FormClosingEventArgs();
                            EventArgs.m_Form = f;
                            FormClosing?.Invoke(this, EventArgs);
                            if (EventArgs.Cancel == false)
                            {
                                f.Close();
                            }
                        }

                        break;
                    }

                case var case4 when case4 == (this.关闭所有ToolStripMenuItem.Name ?? ""):
                    {
                        var list = new List<System.Windows.Forms.Form>();
                        foreach (System.Windows.Forms.Form frm in this.Forms)
                            list.Add(frm);
                        foreach (System.Windows.Forms.Form f in list)
                        {
                            var EventArgs = new FormClosingEventArgs();
                            EventArgs.m_Form = f;
                            FormClosing?.Invoke(this, EventArgs);
                            if (EventArgs.Cancel == false)
                            {
                                f.Close();
                            }
                        }

                        break;
                    }
            }
        }
    }
}